use crate::conf_init::{MapResult, indicator_conf, MapErr};
use crate::indicators::{IndicatorsStoreConf, indicators_values_ref};
use std::time::Duration;
use std::io::Write;
use std::sync::atomic::Ordering;

pub fn indicator_store_run() ->MapResult<()>{
    let conf = indicator_conf();
    if let Some(conf) = conf{
        if let Err(e) = std::thread::Builder::new().name("indicator_store".to_string()).spawn(move ||{
            indicator_store(conf);
        }){
            return MapResult::Err(MapErr::new(format!("indicator_store thread spawn err [{:?}]", e)));
        }
        return MapResult::Ok(());
    }else{
        return MapResult::Ok(());
    }
}

fn indicator_store(conf: &IndicatorsStoreConf){
    info!("indicator_store");

    if conf.enable{
        loop{
            let mut store_file =match std::fs::File::create(&conf.file){
                Ok(t) => {t},
                Err(e) => {
                    error!("indicator_store create file {} err: {}", &conf.file, e);
                    std::process::exit(-1);
                },
            };

            'new_file:
            loop{
                std::thread::sleep(Duration::from_secs(conf.interval));
                let now = chrono::Local::now();
                let now_desc = format!("{}", now.format("-------------------------\n%Y/%m/%d %H:%M:%S\n"));
                if let Err(e) = store_file.write(now_desc.as_bytes()){
                    warn!("indicator_store write err {:?}", e);
                    break 'new_file;
                }

                let indicators_values = indicators_values_ref();
                for (mode, t) in indicators_values.iter(){
                    if let Err(e) = store_file.write(format!("\n{:>16?}", mode).as_bytes()){
                        warn!("indicator_store write err {:?}\n", e);
                        break 'new_file;
                    }
                    for (node,kv) in t.mode.iter(){
                        if let Err(e) = store_file.write(format!("    {:>16}\n", node).as_bytes()){
                            warn!("indicator_store write err {:?}", e);
                            break 'new_file;
                        }
                        for (k,v) in kv.key_value.iter(){
                            if let Err(e) = store_file.write(format!("{:>16} {}\n", k, v.load(Ordering::SeqCst)).as_bytes()){
                                warn!("indicator_store write err {:?}", e);
                                break 'new_file;
                            }
                        }
                    }
                }
            }
        }
    }
}